package top.superflow.core.resource

import java.util.Date

import top.superflow.core.scope.ScopeType
import top.superflow.exception.resource.ResourceUnavailableException

trait PooledResource[T] extends Ordered[PooledResource[T]]{

  private var lastStatusChangeTime = new Date()

  private var status : PooledResourceStatus = IDLE

  private var borrower : Option[_] = None

  def getResourceType : String

  def get : T

  def release

  def getRetention : ScopeType

  def verify

  def getStatus : PooledResourceStatus

  def getLastStatusChangeTime : Date = {
    this.lastStatusChangeTime
  }

  def markStatus(borrower: Option[Any], fromStatus : PooledResourceStatus, toStatus : PooledResourceStatus) = synchronized {
    if(!this.status.equals(fromStatus)){
      throw new ResourceUnavailableException("The current resouce is in status " + status + ", but expect it's in " + fromStatus + ", " +
                                              " it has been borrowed by " + borrower)
    }

    this.borrower = borrower
    this.status = toStatus
    this.lastStatusChangeTime = new Date();
  }

  def compare(that : PooledResource[T]) : Int = {
    if(that == null){
      return -1
    }
    
    if(this.getLastStatusChangeTime == null || that.getLastStatusChangeTime == null){
      throw new IllegalArgumentException("The last status change time should not be null!")
    }
    
    if (this.getLastStatusChangeTime.equals(that.getLastStatusChangeTime))
            0
        else if (this.getLastStatusChangeTime.after(that.getLastStatusChangeTime))
            - 1
        else
            1
  }
  
  override def toString = {
    super.toString()
  }
}